package calendar;

import calendar.messages.*;
import edu.gmu.middleware.CallbackStub;
import edu.gmu.middleware.RemoteStub;
import edu.gmu.middleware.Message;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;

public class CalendarStub implements CalendarObjInt
{
    private RemoteStub           stub = null;
    private CallbackStub callbackStub = null;
    
    /**
     * Creates a new CalendarStub with specified params.
     */
    public CalendarStub(    String host,
                            int port,
                            int id,
                            String name ) throws IOException
    {
        this.stub         = new RemoteStub(   host, port,   id, name );
        this.callbackStub = new CallbackStub( host, port+1, id, name );

        this.stub.register(Topic.USER_RESPONSE,          UserResponse.class);
        this.stub.register(Topic.ISCONNECTED_RESPONSE,   IsconnectedResponse.class);
        this.stub.register(Topic.CLEAR_MEMBERS_RESPONSE, ClearMembersResponse.class);
        this.stub.register(Topic.SCHEDULE_RESPONSE,      ScheduleResponse.class);
        this.stub.register(Topic.RETRIEVE_RESPONSE,      RetrieveResponse.class);
        this.stub.register(Topic.ALIVE_RESPONSE,         AliveResponse.class);
    }
    
    //------------------------------------------------------------------------//
    // Callback stuff
    //------------------------------------------------------------------------//
    public void registerCallback( final CallbackInt callbackInt )
    {
        edu.gmu.middleware.Callback eventCallback = new edu.gmu.middleware.Callback()
        {
            public void execute( Message message )
            {
                NotifyEvent evt = (NotifyEvent)message;
                try
                {
                    callbackInt.notifyClientEvent(evt.event, evt.appt);
                }
                catch(IOException ioe)
                {
                    // will not happen in this context - no more io
                }
            }
        };
        this.callbackStub.register(Topic.NOTIFY_EVENT, NotifyEvent.class, eventCallback);
        
        edu.gmu.middleware.Callback userCallback = new edu.gmu.middleware.Callback()
        {
            public void execute( Message message )
            {
                NotifyUser evt = (NotifyUser)message;
                try
                {
                    callbackInt.notifyClientUser(evt.user, evt.users);
                }
                catch(IOException ioe)
                {
                    // will not happen in this context - no more io
                }
            }
        };
        this.callbackStub.register(Topic.NOTIFY_USER, NotifyUser.class, userCallback);
    }
    
    public void unregisterCallback( )
    {
        this.callbackStub.unregister(Topic.NOTIFY_EVENT);
        this.callbackStub.unregister(Topic.NOTIFY_USER);
    }
    //------------------------------------------------------------------------//

    public ArrayList retrieveEvents(User user, Date start, Date end) throws IOException
    {
        RetrieveRequest r = new RetrieveRequest();
        r.user   = user;
        r.start  = start;
        r.end    = end;
        Message message = this.stub.execute(Topic.RETRIEVE_REQUEST, r);
        RetrieveResponse response = (RetrieveResponse)message;
        return response.events;
    }

    public ArrayList scheduleEvent(ArrayList users, Event newEvent, Event oldEvent, boolean addToThis) throws IOException
    {
        ScheduleRequest r = new ScheduleRequest();
        r.users     = users;
        r.newEvent  = newEvent;
        r.oldEvent  = oldEvent;
        r.addToThis = addToThis;
        Message message = this.stub.execute(Topic.SCHEDULE_REQUEST, r);
        ScheduleResponse response = (ScheduleResponse)message;
        return response.users;
    }

    public char getUserId() throws IOException
    {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public User getUser() throws IOException
    {
        UserRequest request = new UserRequest();
        Message message = this.stub.execute(Topic.USER_REQUEST, request);
        UserResponse response = (UserResponse)message;
        return response.user;
    }

    public boolean isConnected() throws IOException
    {
        IsconnectedRequest request = new IsconnectedRequest();
        Message message = this.stub.execute(Topic.ISCONNECTED_REQUEST, request);
        IsconnectedResponse response = (IsconnectedResponse)message;
        return response.connected;
    }

    public void clearMembers() throws IOException
    {
        ClearMembersRequest request = new ClearMembersRequest();
        Message message = this.stub.execute(Topic.CLEAR_MEMBERS_REQUEST, request);
        ClearMembersResponse response = (ClearMembersResponse)message;
        return;
    }

  public void isAlive() throws IOException {
        AliveRequest request = new AliveRequest();
        Message message = this.stub.execute(Topic.ALIVE_REQUEST, request);
        AliveResponse response = (AliveResponse)message;
        return;
  }
}
